package cn.b.sky.user.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 
 * <strong>Title : ProxyFilter.java<br></strong>
 * <strong>Package : cn.b.sky.user.filter<br></strong>
 * <strong>Description : </strong>代理的filter<br> 
 * <strong>Create on : 2016-7-18 上午9:23:52<br></strong>
 * <p>
 * @author lidapeng<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 * <strong>修改历史:</strong><br>
 * 修改人|修改日期|修改描述<br>
 * -------------------------------------------<br>
 * <br>
 * <br>
 */
public class ProxyFilter implements Filter {

  private String name;

  private Filter filter;

  private UrlPatternMatcher urlPatternMatcher = UrlPatternMatcher.DEFAULT_MATCHER;

  private Map<String, String> map = Collections.emptyMap();

  private boolean enable = true;

  private final List<UrlPatternMatcher> excludes = new ArrayList<UrlPatternMatcher>();

  @Override
  public void destroy() {
    if (this.enable) {
      this.filter.destroy();
    }
  }

  @Override
  public void init(FilterConfig config) throws ServletException {
    if (this.enable) {
      ProxyFilterConfig proxyFilterConfig = new ProxyFilterConfig(config.getServletContext());

      proxyFilterConfig.setFilterName(this.name);
      proxyFilterConfig.setMap(this.map);
      this.filter.init(proxyFilterConfig);
    }
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
      ServletException {
    if (this.enable) {
      HttpServletRequest req = (HttpServletRequest) request;
      HttpServletResponse res = (HttpServletResponse) response;
      String contextPath = req.getContextPath();
      String requestUri = req.getRequestURI();
      String path = requestUri.substring(contextPath.length());

      if (isExcluded(path)) {
        chain.doFilter(request, response);

        return;
      }

      if (this.urlPatternMatcher.shouldRedirect(path)) {
        res.sendRedirect(contextPath + path + "/");
        return;
      }

      if (this.urlPatternMatcher.matches(path)) {
        this.filter.doFilter(request, response, chain);
      } else {
        chain.doFilter(request, response);
      }
    } else {
      chain.doFilter(request, response);
    }
  }

  protected boolean isExcluded(String path) {
    for (UrlPatternMatcher exclude : this.excludes) {
      if (exclude.matches(path)) {
        return true;
      }
    }

    return false;
  }

  public String getName() {
    return this.name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public void setFilter(Filter filter) {
    this.filter = filter;
  }

  public void setUrlPattern(String urlPattern) {
    this.urlPatternMatcher = UrlPatternMatcher.create(urlPattern);
  }

  public void setMap(Map<String, String> map) {
    this.map = map;
  }

  public void setEnable(boolean enable) {
    this.enable = enable;
  }

  public void setExcludePatterns(List<String> excludePatterns) {
    for (String excludePattern : excludePatterns) {
      this.excludes.add(UrlPatternMatcher.create(excludePattern));
    }
  }

}
